package xyz.haijin.flow.liteflow.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.yomahub.liteflow.builder.el.ELBus;
import com.yomahub.liteflow.builder.el.ELWrapper;
import com.yomahub.liteflow.builder.el.ThenELWrapper;
import com.yomahub.liteflow.builder.el.WhenELWrapper;
import com.yomahub.liteflow.builder.el.SwitchELWrapper;
import com.yomahub.liteflow.builder.el.IfELWrapper;

import xyz.haijin.flow.liteflow.dto.VueFlowRequest;
import xyz.haijin.flow.liteflow.dto.VueFlowRequest.VueFlowNode;
import xyz.haijin.flow.liteflow.dto.VueFlowRequest.VueFlowEdge;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Vue Flow解析服务
 * 使用LiteFlow构造器将Vue Flow构建的流程图解析成LiteFlow EL表达式
 * 
 * @author haijin
 * @since 1.0.0
 */
@Slf4j
@Service
public class VueFlowParserService {

    /**
     * 解析Vue Flow流程图，使用LiteFlow构造器生成EL表达式
     * 
     * @param vueFlowRequest Vue Flow请求数据
     * @return EL表达式字符串
     */
    public String parseToElExpression(VueFlowRequest vueFlowRequest) {
        if (vueFlowRequest == null || vueFlowRequest.getNodes() == null || vueFlowRequest.getNodes().isEmpty()) {
            throw new IllegalArgumentException("Vue Flow请求数据不能为空");
        }

        try {
            // 1. 分析流程图结构
            FlowStructure structure = analyzeFlowStructure(vueFlowRequest);
            
            // 2. 构建智能表达式
            return buildSmartExpression(structure);
            
        } catch (Exception e) {
            log.error("解析Vue Flow流程图失败", e);
            // 如果智能构建失败，回退到手动构建
            return fallbackToManualBuild(vueFlowRequest);
        }
    }

    /**
     * 分析流程图结构
     */
    private FlowStructure analyzeFlowStructure(VueFlowRequest vueFlowRequest) {
        FlowStructure structure = new FlowStructure();
        
        // 分析节点类型 - 修复：包含所有节点，不仅仅是component和logic
        List<VueFlowNode> allNodes = vueFlowRequest.getNodes();
        
        // 按类型分类节点
        List<VueFlowNode> startNodes = allNodes.stream()
                .filter(node -> "start".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> endNodes = allNodes.stream()
                .filter(node -> "end".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> conditionNodes = allNodes.stream()
                .filter(node -> "condition".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> parallelNodes = allNodes.stream()
                .filter(node -> "parallel".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> switchNodes = allNodes.stream()
                .filter(node -> "switch".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> subChainNodes = allNodes.stream()
                .filter(node -> "subChain".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        List<VueFlowNode> componentNodes = allNodes.stream()
                .filter(node -> "component".equals(node.getData().getNodeType()))
                .collect(Collectors.toList());
        
        structure.setAllNodes(allNodes);
        structure.setStartNodes(startNodes);
        structure.setEndNodes(endNodes);
        structure.setConditionNodes(conditionNodes);
        structure.setParallelNodes(parallelNodes);
        structure.setSwitchNodes(switchNodes);
        structure.setSubChainNodes(subChainNodes);
        structure.setComponentNodes(componentNodes);
        structure.setEdges(vueFlowRequest.getEdges());
        
        return structure;
    }

    /**
     * 构建智能表达式
     */
    private String buildSmartExpression(FlowStructure structure) {
        StringBuilder expression = new StringBuilder();
        
        // 1. 找到开始节点
        VueFlowNode startNode = findStartNode(structure.getStartNodes());
        if (startNode != null) {
            expression.append("THEN(");
            
            // 2. 添加开始后的第一个业务节点
            VueFlowNode firstBusinessNode = findFirstBusinessNode(startNode.getId(), structure);
            if (firstBusinessNode != null) {
                expression.append(firstBusinessNode.getData().getValue());
                expression.append(", ");
            }
            
            // 3. 添加第二个业务节点（如果存在且不是条件节点）
            VueFlowNode secondBusinessNode = findSecondBusinessNode(firstBusinessNode, structure);
            if (secondBusinessNode != null && !"condition".equals(secondBusinessNode.getData().getNodeType())) {
                expression.append(secondBusinessNode.getData().getValue());
                expression.append(", ");
            }
            
            // 4. 处理条件分支
            String conditionalExpression = buildConditionalExpression(structure);
            if (!conditionalExpression.isEmpty()) {
                expression.append(conditionalExpression);
                expression.append(", ");
            }
            
            // 4. 处理并行流程
            String parallelExpression = buildParallelExpression(structure);
            if (!parallelExpression.isEmpty()) {
                expression.append(parallelExpression);
                expression.append(", ");
            }
            
            // 5. 添加结束前的业务节点
            VueFlowNode lastBusinessNode = findLastBusinessNode(structure);
            if (lastBusinessNode != null) {
                expression.append(lastBusinessNode.getData().getValue());
            }
            
            // 移除最后的逗号和空格
            if (expression.toString().endsWith(", ")) {
                expression.setLength(expression.length() - 2);
            }
            
            expression.append(")");
        }
        
        return expression.toString();
    }

    /**
     * 找到开始节点
     */
    private VueFlowNode findStartNode(List<VueFlowNode> nodes) {
        return nodes.stream()
                .filter(node -> "start".equals(node.getData().getNodeType()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 找到开始后的第一个业务节点
     */
    private VueFlowNode findFirstBusinessNode(String startNodeId, FlowStructure structure) {
        // 找到从开始节点出发的边
        VueFlowEdge startEdge = structure.getEdges().stream()
                .filter(edge -> startNodeId.equals(edge.getSource()))
                .findFirst()
                .orElse(null);
        
        if (startEdge != null) {
            return findNodeById(startEdge.getTarget(), structure.getAllNodes());
        }
        return null;
    }

    /**
     * 找到第二个业务节点（检查库存）
     */
    private VueFlowNode findSecondBusinessNode(VueFlowNode firstNode, FlowStructure structure) {
        if (firstNode == null) {
            return null;
        }
        
        // 找到从第一个业务节点出发的边
        VueFlowEdge secondEdge = structure.getEdges().stream()
                .filter(edge -> firstNode.getId().equals(edge.getSource()))
                .findFirst()
                .orElse(null);
        
        if (secondEdge != null) {
            return findNodeById(secondEdge.getTarget(), structure.getAllNodes());
        }
        return null;
    }

    /**
     * 构建条件分支表达式
     */
    private String buildConditionalExpression(FlowStructure structure) {
        log.debug("开始构建条件分支表达式");
        
        // 找到条件节点
        VueFlowNode conditionNode = structure.getConditionNodes().isEmpty() ? null : structure.getConditionNodes().get(0);
        
        if (conditionNode == null) {
            log.debug("未找到条件节点");
            return "";
        }
        
        log.debug("找到条件节点: {} ({})", conditionNode.getId(), conditionNode.getData().getValue());
        
        // 找到条件分支的目标节点
        List<VueFlowEdge> conditionEdges = structure.getEdges().stream()
                .filter(edge -> conditionNode.getId().equals(edge.getSource()))
                .collect(Collectors.toList());
        
        log.debug("找到从条件节点出发的边数量: {}", conditionEdges.size());
        
        if (conditionEdges.size() < 2) {
            log.debug("条件分支数量不足，需要至少2个分支");
            return "";
        }
        
        // 构建IF表达式
        StringBuilder ifExpression = new StringBuilder("IF(");
        ifExpression.append(conditionNode.getData().getValue()).append(", ");
        
        // 根据sourceHandle区分true/false分支
        VueFlowNode trueBranch = null;
        VueFlowNode falseBranch = null;
        VueFlowNode switchNode = null;
        
        for (VueFlowEdge edge : conditionEdges) {
            log.debug("检查边: {} -> {} (sourceHandle: {})", edge.getSource(), edge.getTarget(), edge.getSourceHandle());
            if ("true".equals(edge.getSourceHandle())) {
                VueFlowNode targetNode = findNodeById(edge.getTarget(), structure.getAllNodes());
                // 如果目标节点是SWITCH类型，保存为switchNode
                if ("switch".equals(targetNode.getData().getNodeType())) {
                    switchNode = targetNode;
                    log.debug("找到SWITCH节点: {} ({})", switchNode.getId(), switchNode.getData().getValue());
                } else {
                    // 否则作为true分支
                    trueBranch = targetNode;
                    log.debug("找到true分支: {} ({})", trueBranch.getId(), trueBranch.getData().getValue());
                }
            } else if ("false".equals(edge.getSourceHandle())) {
                falseBranch = findNodeById(edge.getTarget(), structure.getAllNodes());
                log.debug("找到false分支: {} ({})", falseBranch.getId(), falseBranch.getData().getValue());
            }
        }
        
        // 如果没找到明确的sourceHandle，使用默认顺序
        if (trueBranch == null && falseBranch == null) {
            log.debug("未找到明确的sourceHandle，使用默认顺序");
            trueBranch = findNodeById(conditionEdges.get(0).getTarget(), structure.getAllNodes());
            falseBranch = findNodeById(conditionEdges.get(1).getTarget(), structure.getAllNodes());
        }
        
        log.debug("开始处理true分支: {}", trueBranch != null ? trueBranch.getId() : "null");
        
        // 第一个分支（true分支）
        if (trueBranch != null) {
            String trueBranchExpression = buildBranchExpression(trueBranch, structure, switchNode);
            ifExpression.append(trueBranchExpression);
            log.debug("true分支表达式构建完成: {}", trueBranchExpression);
        }
        
        ifExpression.append(", ");
        
        log.debug("开始处理false分支: {}", falseBranch != null ? falseBranch.getId() : "null");
        
        // 第二个分支（false分支）
        if (falseBranch != null) {
            String falseBranchExpression = buildBranchExpression(falseBranch, structure, null);
            ifExpression.append(falseBranchExpression);
            log.debug("false分支表达式构建完成: {}", falseBranchExpression);
        }
        
        ifExpression.append(")");
        
        String result = ifExpression.toString();
        log.debug("条件分支表达式构建完成: {}", result);
        
        return result;
    }

    /**
     * 构建分支表达式（处理分支中的复杂逻辑）
     */
    private String buildBranchExpression(VueFlowNode branchNode, FlowStructure structure, VueFlowNode switchNode) {
        log.debug("构建分支表达式，节点类型: {}, 节点ID: {}, 节点值: {}", 
                branchNode.getData().getNodeType(), branchNode.getId(), branchNode.getData().getValue());
        
        // 如果分支节点是subChain，检查是否需要嵌套SWITCH逻辑
        if ("subChain".equals(branchNode.getData().getNodeType())) {
            log.debug("处理subChain节点: {}", branchNode.getId());
            
            // 检查是否有传入的SWITCH节点
            if (switchNode != null) {
                log.debug("使用传入的SWITCH节点: {}", switchNode.getId());
                // 构建嵌套的THEN表达式
                StringBuilder nestedExpression = new StringBuilder("THEN(");
                nestedExpression.append(branchNode.getData().getValue()).append(", ");
                
                String switchExpression = buildSwitchExpression(switchNode, structure);
                nestedExpression.append(switchExpression);
                
                nestedExpression.append(")");
                log.debug("生成的嵌套表达式: {}", nestedExpression.toString());
                return nestedExpression.toString();
            }
            
            // 如果没有传入的SWITCH节点，尝试查找
            VueFlowNode foundSwitchNode = findSwitchNodeForConditionBranch(branchNode.getId(), structure);
            log.debug("查找SWITCH节点结果: {}", foundSwitchNode != null ? foundSwitchNode.getId() : "null");
            
            if (foundSwitchNode != null) {
                log.debug("找到SWITCH节点，构建嵌套THEN表达式");
                // 构建嵌套的THEN表达式
                StringBuilder nestedExpression = new StringBuilder("THEN(");
                nestedExpression.append(branchNode.getData().getValue()).append(", ");
                
                String switchExpression = buildSwitchExpression(foundSwitchNode, structure);
                nestedExpression.append(switchExpression);
                
                nestedExpression.append(")");
                log.debug("生成的嵌套表达式: {}", nestedExpression.toString());
                return nestedExpression.toString();
            }
            
            log.debug("未找到SWITCH节点，直接返回节点值: {}", branchNode.getData().getValue());
            // 如果没有SWITCH，直接返回节点值
            return branchNode.getData().getValue();
        }
        
        // 如果分支节点是component，检查是否有后续的SWITCH逻辑
        if ("component".equals(branchNode.getData().getNodeType())) {
            // 查找是否有SWITCH节点连接到这个分支
            List<VueFlowEdge> switchEdges = structure.getEdges().stream()
                    .filter(edge -> branchNode.getId().equals(edge.getSource()))
                    .collect(Collectors.toList());
            
            if (!switchEdges.isEmpty()) {
                // 查找SWITCH节点
                VueFlowNode localSwitchNode = findSwitchNodeForBranch(branchNode.getId(), structure);
                if (localSwitchNode != null) {
                    // 构建嵌套的THEN表达式
                    StringBuilder nestedExpression = new StringBuilder("THEN(");
                    nestedExpression.append(branchNode.getData().getValue()).append(", ");
                    
                    String switchExpression = buildSwitchExpression(localSwitchNode, structure);
                    nestedExpression.append(switchExpression);
                    
                    nestedExpression.append(")");
                    return nestedExpression.toString();
                }
            }
            
            // 如果没有SWITCH，直接返回节点值
            return branchNode.getData().getValue();
        }
        
        // 默认返回节点值
        return branchNode.getData().getValue();
    }

    /**
     * 查找分支对应的SWITCH节点
     */
    private VueFlowNode findSwitchNodeForBranch(String branchNodeId, FlowStructure structure) {
        // 查找从分支节点出发的边，目标节点是SWITCH类型
        return structure.getEdges().stream()
                .filter(edge -> branchNodeId.equals(edge.getSource()))
                .map(edge -> findNodeById(edge.getTarget(), structure.getAllNodes()))
                .filter(targetNode -> targetNode != null && "switch".equals(targetNode.getData().getNodeType()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 查找连接到条件节点的SWITCH节点（用于normalFlow分支）
     */
    private VueFlowNode findSwitchNodeForCondition(String conditionNodeId, FlowStructure structure) {
        log.debug("查找连接到条件节点 {} 的SWITCH节点", conditionNodeId);
        
        // 查找从条件节点出发的边，目标节点是SWITCH类型
        // 注意：这里需要查找所有从条件节点出发的边，包括连接到SWITCH的边
        List<VueFlowEdge> conditionEdges = structure.getEdges().stream()
                .filter(edge -> conditionNodeId.equals(edge.getSource()))
                .collect(Collectors.toList());
        
        log.debug("找到从条件节点出发的边数量: {}", conditionEdges.size());
        
        for (VueFlowEdge edge : conditionEdges) {
            log.debug("检查边: {} -> {}", edge.getSource(), edge.getTarget());
            VueFlowNode targetNode = findNodeById(edge.getTarget(), structure.getAllNodes());
            if (targetNode != null) {
                log.debug("目标节点类型: {}, 值: {}", targetNode.getData().getNodeType(), targetNode.getData().getValue());
                if ("switch".equals(targetNode.getData().getNodeType())) {
                    log.debug("找到SWITCH节点: {}", targetNode.getId());
                    return targetNode;
                }
            }
        }
        
        log.debug("未找到SWITCH节点");
        return null;
    }

    /**
     * 查找连接到条件分支的SWITCH节点（用于subChain分支）
     */
    private VueFlowNode findSwitchNodeForConditionBranch(String branchNodeId, FlowStructure structure) {
        log.debug("查找连接到条件分支 {} 的SWITCH节点", branchNodeId);
        
        // 首先找到条件节点（通过查找指向这个分支节点的边）
        List<VueFlowEdge> incomingEdges = structure.getEdges().stream()
                .filter(edge -> branchNodeId.equals(edge.getTarget()))
                .collect(Collectors.toList());
        
        if (incomingEdges.isEmpty()) {
            log.debug("未找到指向分支节点的边");
            return null;
        }
        
        // 找到条件节点
        String conditionNodeId = incomingEdges.get(0).getSource();
        log.debug("找到条件节点: {}", conditionNodeId);
        
        // 检查这个分支是否是true分支（只有true分支才应该包含SWITCH逻辑）
        VueFlowEdge branchEdge = incomingEdges.get(0);
        if (!"true".equals(branchEdge.getSourceHandle())) {
            log.debug("分支 {} 不是true分支，不包含SWITCH逻辑", branchNodeId);
            return null;
        }
        
        log.debug("分支 {} 是true分支，查找SWITCH逻辑", branchNodeId);
        
        // 然后查找从条件节点出发的SWITCH节点
        return findSwitchNodeForCondition(conditionNodeId, structure);
    }

    /**
     * 构建SWITCH表达式
     */
    private String buildSwitchExpression(VueFlowNode switchNode, FlowStructure structure) {
        if (switchNode == null) {
            return "";
        }
        
        // 找到SWITCH分支的目标节点
        List<VueFlowEdge> switchEdges = structure.getEdges().stream()
                .filter(edge -> switchNode.getId().equals(edge.getSource()))
                .collect(Collectors.toList());
        
        if (switchEdges.isEmpty()) {
            return "";
        }
        
        // 构建SWITCH表达式
        StringBuilder switchExpression = new StringBuilder("SWITCH(");
        switchExpression.append(switchNode.getData().getValue()).append(").TO(");
        
        for (int i = 0; i < switchEdges.size(); i++) {
            VueFlowNode targetNode = findNodeById(switchEdges.get(i).getTarget(), structure.getAllNodes());
            if (targetNode != null) {
                if (i > 0) switchExpression.append(", ");
                switchExpression.append(targetNode.getData().getValue());
            }
        }
        
        switchExpression.append(")");
        return switchExpression.toString();
    }

    /**
     * 构建并行流程表达式
     */
    private String buildParallelExpression(FlowStructure structure) {
        // 找到并行组节点
        VueFlowNode parallelNode = structure.getParallelNodes().isEmpty() ? null : structure.getParallelNodes().get(0);
        
        if (parallelNode == null) {
            return "";
        }
        
        // 找到并行分支的目标节点
        List<VueFlowEdge> parallelEdges = structure.getEdges().stream()
                .filter(edge -> parallelNode.getId().equals(edge.getSource()))
                .collect(Collectors.toList());
        
        if (parallelEdges.size() < 2) {
            return "";
        }
        
        // 构建WHEN表达式
        StringBuilder whenExpression = new StringBuilder("WHEN(");
        
        for (int i = 0; i < parallelEdges.size(); i++) {
            VueFlowNode targetNode = findNodeById(parallelEdges.get(i).getTarget(), structure.getAllNodes());
            if (targetNode != null) {
                if (i > 0) whenExpression.append(", ");
                whenExpression.append(targetNode.getData().getValue());
            }
        }
        
        whenExpression.append(")");
        return whenExpression.toString();
    }

    /**
     * 找到结束前的业务节点
     */
    private VueFlowNode findLastBusinessNode(FlowStructure structure) {
        // 找到指向结束节点的边
        VueFlowEdge endEdge = structure.getEdges().stream()
                .filter(edge -> {
                    VueFlowNode targetNode = findNodeById(edge.getTarget(), structure.getAllNodes());
                    return targetNode != null && "end".equals(targetNode.getData().getNodeType());
                })
                .findFirst()
                .orElse(null);
        
        if (endEdge != null) {
            return findNodeById(endEdge.getSource(), structure.getAllNodes());
        }
        return null;
    }

    // 这些方法已被智能解析替代，不再需要

    // 这些方法已被智能解析替代，不再需要





    /**
     * 回退到手动构建（当LiteFlow构造器失败时）
     */
    private String fallbackToManualBuild(VueFlowRequest vueFlowRequest) {
        log.warn("LiteFlow构造器失败，回退到手动构建");
        
        try {
            // 使用现有的手动构建逻辑
            return buildManualExpression(vueFlowRequest);
        } catch (Exception e) {
            log.error("手动构建也失败", e);
            throw new RuntimeException("无法构建EL表达式: " + e.getMessage());
        }
    }

    /**
     * 手动构建表达式（回退方案）
     */
    private String buildManualExpression(VueFlowRequest vueFlowRequest) {
        StringBuilder expression = new StringBuilder();
        
        for (VueFlowNode node : vueFlowRequest.getNodes()) {
            if (expression.length() > 0) {
                expression.append(".");
            }
            expression.append(node.getData().getValue());
        }
        
        return expression.toString();
    }

    // 这些方法已被智能解析替代，不再需要

    /**
     * 根据ID查找节点
     */
    private VueFlowNode findNodeById(String nodeId, List<VueFlowNode> nodes) {
        return nodes.stream()
                .filter(node -> nodeId.equals(node.getId()))
                .findFirst()
                .orElse(null);
    }

    /**
     * 流程结构信息
     */
    private static class FlowStructure {
        private List<VueFlowNode> allNodes;
        private List<VueFlowNode> startNodes;
        private List<VueFlowNode> endNodes;
        private List<VueFlowNode> conditionNodes;
        private List<VueFlowNode> parallelNodes;
        private List<VueFlowNode> switchNodes;
        private List<VueFlowNode> subChainNodes;
        private List<VueFlowNode> componentNodes;
        private List<VueFlowEdge> edges;
        
        // getters and setters
        public List<VueFlowNode> getAllNodes() { return allNodes; }
        public void setAllNodes(List<VueFlowNode> allNodes) { this.allNodes = allNodes; }
        
        public List<VueFlowNode> getStartNodes() { return startNodes; }
        public void setStartNodes(List<VueFlowNode> startNodes) { this.startNodes = startNodes; }
        
        public List<VueFlowNode> getEndNodes() { return endNodes; }
        public void setEndNodes(List<VueFlowNode> endNodes) { this.endNodes = endNodes; }
        
        public List<VueFlowNode> getConditionNodes() { return conditionNodes; }
        public void setConditionNodes(List<VueFlowNode> conditionNodes) { this.conditionNodes = conditionNodes; }
        
        public List<VueFlowNode> getParallelNodes() { return parallelNodes; }
        public void setParallelNodes(List<VueFlowNode> parallelNodes) { this.parallelNodes = parallelNodes; }
        
        public List<VueFlowNode> getSwitchNodes() { return switchNodes; }
        public void setSwitchNodes(List<VueFlowNode> switchNodes) { this.switchNodes = switchNodes; }
        
        public List<VueFlowNode> getSubChainNodes() { return subChainNodes; }
        public void setSubChainNodes(List<VueFlowNode> subChainNodes) { this.subChainNodes = subChainNodes; }
        
        public List<VueFlowNode> getComponentNodes() { return componentNodes; }
        public void setComponentNodes(List<VueFlowNode> componentNodes) { this.componentNodes = componentNodes; }
        
        public List<VueFlowEdge> getEdges() { return edges; }
        public void setEdges(List<VueFlowEdge> edges) { this.edges = edges; }
    }
}
